package com.janetfilter.core.utils;

import com.janetfilter.core.Launcher;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;

/**
 * 工具定位工具类
 * 用于查找Java相关的工具和文件，如jps、java可执行文件和tools.jar
 * 同时提供获取当前JAR文件URI的方法
 */
public class WhereIsUtils {
    // Java安装目录，通过系统属性获取
    private static final String JAVA_HOME = System.getProperty("java.home");

    /**
     * 查找JPS可执行文件（Java进程状态工具）
     * 在不同的可能路径中搜索jps或jps.exe
     * 
     * @return JPS可执行文件对象，如果未找到则返回null
     */
    public static File findJPS() {
        // 可能的JPS路径
        String[] paths = new String[]{"bin/jps", "bin/jps.exe", "../bin/jps", "../bin/jps.exe"};

        // 遍历所有可能的路径
        for (String path : paths) {
            File file = new File(JAVA_HOME, path);
            // 检查文件是否存在、是否是文件、是否可执行
            if (file.exists() && file.isFile() && file.canExecute()) {
                return getCanonicalFile(file);
            }
        }

        return null;
    }

    /**
     * 查找Java可执行文件
     * 在不同的可能路径中搜索java或java.exe
     * 
     * @return Java可执行文件对象，如果未找到则返回null
     */
    public static File findJava() {
        // 可能的Java路径
        String[] paths = new String[]{"bin/java", "bin/java.exe", "../bin/java", "../bin/java.exe"};

        // 遍历所有可能的路径
        for (String path : paths) {
            File file = new File(JAVA_HOME, path);
            // 检查文件是否存在、是否是文件、是否可执行
            if (file.exists() && file.isFile() && file.canExecute()) {
                return getCanonicalFile(file);
            }
        }

        return null;
    }

    /**
     * 查找tools.jar文件
     * tools.jar包含JDK工具类，如VirtualMachine（用于Attach API）
     * 
     * @return tools.jar文件对象，如果未找到则返回null
     */
    public static File findToolsJar() {
        // 可能的tools.jar路径
        String[] paths = new String[]{"lib/tools.jar", "../lib/tools.jar", "../../lib/tools.jar"};

        // 遍历所有可能的路径
        for (String path : paths) {
            File file = new File(JAVA_HOME, path);
            // 检查文件是否存在且是文件
            if (file.exists() && file.isFile()) {
                return getCanonicalFile(file);
            }
        }

        return null;
    }

    /**
     * 获取当前JAR文件的URI
     * 尝试两种方式：
     * 1. 直接从代码源获取
     * 2. 通过资源文件定位
     * 
     * @return 当前JAR文件的URI
     * @throws Exception 如果无法定位JAR文件
     */
    public static URI getJarURI() throws Exception {
        // 尝试从代码源直接获取
        URL url = Launcher.class.getProtectionDomain().getCodeSource().getLocation();
        if (null != url) {
            return url.toURI();
        }

        // 如果直接获取失败，尝试通过资源文件定位
        String resourcePath = "/6c81ec87e55d331c267262e892427a3d93d76683.txt";
        url = Launcher.class.getResource(resourcePath);
        if (null == url) {
            throw new Exception("Can not locate resource file.");
        }

        // 从资源URL中提取JAR路径
        String path = url.getPath();
        if (!path.endsWith("!" + resourcePath)) {
            throw new Exception("Invalid resource path.");
        }

        // 移除资源路径部分，只保留JAR路径
        path = path.substring(0, path.length() - resourcePath.length() - 1);

        return new URI(path);
    }

    /**
     * 获取文件的规范形式（解析符号链接等）
     * 
     * @param file 原始文件对象
     * @return 规范形式的文件对象，如果获取失败则返回null
     */
    private static File getCanonicalFile(File file) {
        try {
            return file.getCanonicalFile();
        } catch (IOException e) {
            return null;
        }
    }
}
